﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace ESRI.ArcGIS.Client.Async
{
    public static partial class ArcGISWebClientExtensions
    {
        #region DownloadStringTaskAsync

        /// <summary>
        /// Downloads asynchronously the resource specified as a System.Uri.
        /// </summary>
        /// <param name="webClient"></param>
        /// <param name="uri">A System.Uri containing the URI to download.</param>
        /// <param name="parameters">The collection of query key/value pairs associated with the request.</param>
        /// <param name="httpMethod">The HTTP method to use.</param>
        /// <returns></returns>
        public static Task<string> DownloadStringTaskAsync(this ArcGISWebClient webClient, Uri uri,
            IDictionary<string, string> parameters = null,
            ArcGISWebClient.HttpMethods httpMethod = ArcGISWebClient.HttpMethods.Auto)
        {
            return DownloadStringTaskAsync(webClient, uri, parameters, httpMethod, CancellationToken.None);
        }

        /// <summary>
        /// Downloads asynchronously the resource specified as a System.Uri.
        /// </summary>
        /// <param name="webClient"></param>
        /// <param name="uri">A System.Uri containing the URI to download.</param>
        /// <param name="parameters">The collection of query key/value pairs associated with the request.</param>
        /// <param name="httpMethod">The HTTP method to use.</param>
        /// <param name="cancellationToken">Cancellation token for cancelling task.</param>
        /// <returns></returns>
        public static Task<string> DownloadStringTaskAsync(this ArcGISWebClient webClient, Uri uri,
            IDictionary<string, string> parameters, ArcGISWebClient.HttpMethods httpMethod,
            CancellationToken cancellationToken)
        {
            return TaskServices
                .HandleAsyncOperation<ArcGISWebClient, ArcGISWebClient.DownloadStringCompletedEventArgs, string>(
                    webClient,
                    s => s.DownloadStringAsync(uri, parameters, httpMethod),
                    (s, e) => s.DownloadStringCompleted += e,
                    (s, e) => webClient.DownloadStringCompleted -= e,
                    s => s.CancelAsync(),
                    e => e.Result,
                    cancellationToken);
        }

        #endregion

        #region OpenReadTaskAsync

        public static Task<Stream> OpenReadTaskAsync(this ArcGISWebClient webClient, Uri uri,
            IDictionary<string, string> parameters = null,
            ArcGISWebClient.HttpMethods httpMethod = ArcGISWebClient.HttpMethods.Auto)
        {
            return OpenReadTaskAsync(webClient, uri, parameters, httpMethod, CancellationToken.None);
        }

        public static Task<Stream> OpenReadTaskAsync(this ArcGISWebClient webClient, Uri uri,
            IDictionary<string, string> parameters, ArcGISWebClient.HttpMethods httpMethod,
            CancellationToken cancellationToken)
        {
            return TaskServices
                .HandleAsyncOperation<ArcGISWebClient, ArcGISWebClient.OpenReadCompletedEventArgs, Stream>(
                    webClient,
                    s => s.OpenReadAsync(uri, parameters, httpMethod),
                    (s, e) => s.OpenReadCompleted += e,
                    (s, e) => s.OpenReadCompleted -= e,
                    s => s.CancelAsync(),
                    e => e.Result,
                    cancellationToken);
        }

        #endregion

        #region PostMultipartTaskAsync

        public static Task<Stream> PostMultipartTaskAsync(this ArcGISWebClient webClient, Uri uri,
            IDictionary<string, string> parameters = null,
            IEnumerable<ArcGISWebClient.StreamContent> streamContents = null)
        {
            return PostMultipartTaskAsync(webClient, uri, parameters, streamContents, CancellationToken.None);
        }

        public static Task<Stream> PostMultipartTaskAsync(this ArcGISWebClient webClient, Uri uri,
            IDictionary<string, string> parameters, IEnumerable<ArcGISWebClient.StreamContent> streamContents,
            CancellationToken cancellationToken)
        {
            return TaskServices
                .HandleAsyncOperation<ArcGISWebClient, ArcGISWebClient.PostMultipartCompletedEventArgs, Stream>(
                    webClient,
                    s => s.PostMultipartAsync(uri, parameters, streamContents),
                    (s, e) => webClient.PostMultipartCompleted += e,
                    (s, e) => webClient.PostMultipartCompleted -= e,
                    s => s.CancelAsync(),
                    e => e.Result,
                    cancellationToken);
        }

        #endregion

    }
}